package com.shockweb.rpc;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.shockweb.bridge.Service;
import com.shockweb.bridge.ServiceHost;
import com.shockweb.bridge.ServiceSpace;
import com.shockweb.common.log.LogManager;
import com.shockweb.rpc.data.ServiceRoot;


/**
 * 与注册服务器同步数据的服务
 * 
 * @author 彭明华
 * 2018年1月3日 创建
 */
public class SyncThread implements Runnable{

	
	/**
	 * 启动的同步线程
	 */
	private Thread thread = null;

	/**
	 * rpc管理器
	 */
	private ClientManager clientManager = null;
	
	/**
	 * 启动同步服务
	 * @param clientManager
	 */
	public void start(ClientManager clientManager) {
		this.clientManager = clientManager;
		if(!started){
			thread = new Thread(this);
			thread.start();
			while(!started){
				try {
					Thread.sleep(1);
				} catch (InterruptedException e) {
				}
			}
		}
	}

	/**
	 * 启动标志
	 */
	private volatile boolean started = false;
	
	/**
	 * 是否停止
	 */
	private volatile boolean stop = false;
	

	/**
	 * 公共延迟方法
	 */
    private void timeDelay(int time) {
		try {
			long t = time - System.currentTimeMillis() % time;
			if (t > 0) {
				Thread.sleep(t);
			}
		} catch (InterruptedException e) {
		}
	}
    
	/**
	 * 同步方法
	 */
	public void run() {
		started = false;
		stop = false;
		while(!stop){
			Map<String,ServiceSpace> serviceSpaces = null;
			try{
				serviceSpaces = clientManager.getRegisterClient().queryServices();
				
				Iterator<Entry<String,ServiceSpace>> serviceSpaceIts = serviceSpaces.entrySet().iterator();
				while(serviceSpaceIts.hasNext()){
					List<String> hosts = new ArrayList<String>();
					Entry<String,ServiceSpace> serviceSpaceEntry = serviceSpaceIts.next();
					ServiceSpace serviceSpace = serviceSpaceEntry.getValue();
					Iterator<Entry<String,ServiceHost>> serviceHosts = serviceSpace.getServiceHosts().entrySet().iterator();
					while(serviceHosts.hasNext()){
						Entry<String,ServiceHost> serviceHostEntry = serviceHosts.next();
						ServiceHost serviceHost = serviceHostEntry.getValue();
						if(serviceHost.getThreshold()>0 && serviceHost.getDoing()>serviceHost.getThreshold()){
							hosts.add(serviceHostEntry.getKey());
						}else if(serviceHost.getCalled()>0 && 1.0*serviceHost.getTimeOut()/serviceHost.getCalled()>0.5){
							hosts.add(serviceHostEntry.getKey());
						}
					}
					if(!hosts.isEmpty()){
						Iterator<Entry<String,Service>> services = serviceSpace.getServices().entrySet().iterator();
						while(services.hasNext()){
							Entry<String,Service> serviceEntry = services.next();
							for(String host:hosts){
								serviceEntry.getValue().getServiceHosts().remove(host);
							}
						}
					}
				}
			} catch (Throwable e) {
				LogManager.errorLog(SyncThread.class,"获取注册服务器服务信息出错",e);
			}
			if(serviceSpaces!=null){
				serviceRoot.putServiceSpace(serviceSpaces);
			}
			started = true;
			clientManager.refresh();
			if(clientManager.getConfig().getSyncThreadSleepTime()>0){
				timeDelay(clientManager.getConfig().getSyncThreadSleepTime());
			}
		}
	}
	
	/**
	 * 当前注册服务器所有服务信息
	 */
	private ServiceRoot serviceRoot;
	
	/**
	 * 构造方法
	 * @param serviceRoot
	 */
	public SyncThread(ServiceRoot serviceRoot){
		this.serviceRoot = serviceRoot;
	}
	
	/**
	 * 停止服务
	 */
	public void stop() {
		started = false;
		stop = true;
		while(thread!=null && thread.isAlive()){
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
			}
		}
	}

}
